package com.springdata.service.impl;

import com.springdata.dao.CustInfoDao;
import com.springdata.pojo.CustInfo;
import com.springdata.service.CustInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.*;
import java.util.List;
import java.util.Optional;

/**
 * @author xwli
 * @date: 2021/10/5 15:38
 * @desc
 * @since JDK 1.8
 */
@Service
public class CustInfoServiceImpl implements CustInfoService {

    @Autowired
    private CustInfoDao custInfoDao;

    @Override
    public CustInfo getCustInfoByNo(Long custNo) {
        return custInfoDao.findByCustNo(custNo);
    }

    @Override
    public CustInfo getCustInfoByName(String custName) {
        return custInfoDao.findJpqlByName(custName);
    }

    @Override
    public CustInfo getCustInfoByAge(String custAge) {
        return custInfoDao.findJpqlByAge(custAge);
    }

    @Override
    public CustInfo getCustInfoByNameAndAge(String custName, String custAge) {
        return custInfoDao.findJpqlByNameAndAge(custName,custAge);
    }

    @Override
    @Transactional
    public void updateCustInfo(Long custNo, String custName) {
        custInfoDao.updateCustInfo(custNo,custName);
    }


    /**
     * 动态查询
     * 自定义查询条件
     *      1.实现Specification接口(提供泛型：查询的对象类型)
     *      2.实现toPredicate方法(构造查询条件)
     *      3.需要借助方法参数中的两个参数(
     *          root:获取需要查询的对象属性
     *          CriteriaBuilder：构造查询条件的，内部封装了很多的查询条件(模糊匹配，精准匹配)
     *      )
     */

    /**
     * 单个条件查询
     * @param custNo
     * @return
     */
    public CustInfo findOneCustInfoByCustNo(Long custNo){

        //匿名内部类
        Specification<CustInfo> specification = new Specification<CustInfo>() {
            @Override
            public Predicate toPredicate(Root<CustInfo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                //1.获取比较的属性
                Path<Object> custNoQuery = root.get("custNo");
                //2.构造查询条件 select * from cust_info where custno = ?;
                Predicate predicate = criteriaBuilder.equal(custNoQuery, custNo);//进行精准匹配(比较的属性，属性值)
                return predicate;
            }
        };
        Optional<CustInfo> one = custInfoDao.findOne(specification);
        CustInfo custInfo = one.get();
        return custInfo;
    }

    /**
     * 多个条件查询
     * @param custNo
     * @param custName
     * @return
     */
    public CustInfo findOneCustInfoByCustNoAndCustName(Long custNo,String custName){

        //匿名内部类
        Specification<CustInfo> specification = new Specification<CustInfo>() {
            @Override
            public Predicate toPredicate(Root<CustInfo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                //1.获取比较的属性
                Path<Object> custNoQuery = root.get("custNo");
                Path<Object> custNameQuery = root.get("custName");
                //2.构造查询条件 select * from cust_info where custno = ? and custname = ?;
                Predicate predicateCustNo = criteriaBuilder.equal(custNoQuery, custNo);//进行精准匹配(比较的属性，属性值)
                Predicate predicateCustName = criteriaBuilder.equal(custNameQuery, custName);
                //3.将多个查询条件组合到一起
                Predicate and = criteriaBuilder.and(predicateCustNo, predicateCustName);
                return and;
            }
        };
        Optional<CustInfo> one = custInfoDao.findOne(specification);
        CustInfo custInfo = one.get();
        return custInfo;
    }

    public List<CustInfo> findAllCustInfoLikeCustName(String custName){

        //匿名内部类
        Specification<CustInfo> specification = new Specification<CustInfo>() {
            @Override
            public Predicate toPredicate(Root<CustInfo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                //1.获取比较的属性
                Path<Object> custNameQuery = root.get("custName");
                //2.构造查询条件 select * from cust_info where custname like ?; 模糊查询
                Predicate like = criteriaBuilder.like(custNameQuery.as(String.class), custName);
                return like;
            }
        };
        List<CustInfo> custInfoList = custInfoDao.findAll(specification);
        return custInfoList;
    }

}

